﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection.Metadata;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace RayD.Core
{
    /// <summary>
    /// Xml工具类
    /// </summary>
    public static class XmlHelper
    {
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="obj">实体对象</param>
        public static string ToXml<T>(T obj)
        {
            try
            {
                MemoryStream stream = new MemoryStream();
                XmlSerializer xmlSer = new XmlSerializer(typeof(T));
                xmlSer.Serialize(stream, obj);

                stream.Position = 0;
                StreamReader sr = new StreamReader(stream);
                return sr.ReadToEnd();
            }
            catch (Exception ex)
            {
                throw new Exception("将实体对象转换成XML异常", ex);
            }
        }

        /// <summary>
        /// 将XML转换成实体对象
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="strXML">XML</param>
        public static T ToClass<T>(string strXML) where T : class
        {
            try
            {
                using StringReader sr = new StringReader(strXML);
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                return serializer.Deserialize(sr) as T;
            }
            catch (Exception ex)
            {
                throw new Exception("将XML转换成实体对象异常", ex);
            }
        }


        /// <summary>
        /// 将一个对象序列化为XML字符串
        /// </summary>
        /// <param name="o">要序列化的对象</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>序列化产生的XML字符串</returns>
        public static string XmlSerialize(object obj, Dictionary<string, string> nameSpaces, Encoding encoding)
        {
            if (obj == null)
                throw new ArgumentNullException("obj");
            if (encoding == null)
                throw new ArgumentNullException("encoding");


            try
            {
                string xml = "";

                using (MemoryStream stream = new MemoryStream())
                {
                    XmlWriterSettings settings = new XmlWriterSettings();
                    settings.Encoding = encoding;

                    //OmitXmlDeclaration表示不生成声明头，默认是false，OmitXmlDeclaration为true，会去掉<?xml version="1.0" encoding="UTF-8"?>
                    //settings.OmitXmlDeclaration = true;

                    XmlWriter writer = XmlWriter.Create(stream, settings);

                    XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
                    if (nameSpaces != null && nameSpaces.Keys.Count > 0)
                    {
                        //强制指定命名空间，覆盖默认的命名空间，可以添加多个，如果要在xml节点上添加指定的前缀，可以在跟节点的类上面添加[XmlRoot(Namespace = "http://www.w3.org/2001/XMLSchema-instance", IsNullable = false)]，Namespace指定哪个值，xml节点添加的前缀就是哪个命名空间(这里会添加ceb)
                        //namespaces.Add("ceb", "http://www.chinaport.gov.cn/ceb");
                        //namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

                        foreach (var key in nameSpaces.Keys)
                        {
                            namespaces.Add(key, nameSpaces[key]);
                        }
                    }

                    XmlSerializer serializer = new XmlSerializer(obj.GetType());
                    serializer.Serialize(writer, obj, namespaces);
                    writer.Close();

                    stream.Position = 0;
                    using (StreamReader reader = new StreamReader(stream, encoding))
                    {
                        xml = reader.ReadToEnd();
                    }
                }

                return xml;
            }
            catch (Exception ex)
            {
                throw new Exception("将实体对象转换成XML异常", ex);
            }

        }

    }
}